/*****************************************************************************
 *
 * Weber State University
 * CS4280 Spring 2010
 * Group Assignment 5
 *
 *
 *   TTTTTT                               CCCCC
 *     TT   EEEEE   A    M   M          CC      C
 *     TT   E      A A   M   M         CC   
 *     TT   E     A   A  MM MM  -----  CC
 *     TT   EEE   AAAAA  M M M  -----  CC
 *     TT   E     A   A  M   M          CC      C
 *     TT   EEEEE A   A  M   M            CCCCC
 *
 *   Jared Pack ---- Jon Mann ---- Joshua Clayton
 *
 *
 * A flythrough of a simple textured 3D scene
 *
 ****************************************************************************/

 /* FILENAME skybox.cpp
  *
  * Change control Section
  *
  * Team Member: Joshua Clayton
  * Version: 0.1
  * Date: 03/19/2010
  *     
  *     
  */

#include "skybox.h"

Skybox::Skybox()
{
}

Skybox::~Skybox()
{
    UnloadTextures();
}

void Skybox::LoadTexture(GLushort side, char *filename)
{
    if (side > 5)
       return; //TODO throw an exception here.
    texture[side].LoadTexture(filename);
	glGenTextures(1, &texture[side].texID);
 //   glBindTexture(GL_TEXTURE_2D, texture[side].texID);
 //   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
 //   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    
    /* 2d texture, level of detail 0 (normal),
     * 3 components (red, green, blue), x size from image,
     * y size from image, border 0 (normal),
     * rgb color data, unsigned byte data, and finally the data itself. */
//    glTexImage2D(GL_TEXTURE_2D, 0, 4, texture[side].width, texture[side].height,
//                 0, GL_RGBA, GL_UNSIGNED_BYTE, texture[side].data);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, 4, texture[side].width, texture[side].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture[side].data);
}

void Skybox::LoadTextures(char *filename[6])
{
    for (int i = 0; i < 6; ++i)
    {
        texture[i].LoadTexture(filename[i]);
    }
}

void Skybox::UnloadTexture(GLushort side)
{
    if (side > 5)
       return; //TODO throw an exception here.
    texture[side].Unload();
}

void Skybox::UnloadTextures()
{
    for (int i = 0; i < 6; ++i)
    {
        texture[i].Unload();
    }
}

void Skybox::Draw(CCamera &c)
{
    glPushMatrix();
    glTranslatef(c.position.x, c.position.y, c.position.z);
    glDisable(GL_DEPTH_TEST);
	glDisable(GL_LIGHTING);
    DrawCube(texture, 10.0);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
	c.SetLights();
    glPopMatrix();
}

/* function draws 6 adjoining textures */
void Skybox::DrawCube(CTexture texture[6], GLfloat size)
{
    size /= -2.0;

    glBegin(GL_QUADS);                        // begin drawing a cube
    // Front Face (note that the texture's corners have to match the quad's corners)
    glBindTexture(GL_TEXTURE_2D,texture[0].texID);
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f(-size, -size,  size);    // Bottom Left Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f( size, -size,  size);    // Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f( size,  size,  size);    // Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f(-size,  size,  size);    // Top Left Of The Texture and Quad
    
    // Back Face
    glBindTexture(GL_TEXTURE_2D,texture[1].texID);
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f(-size, -size, -size);    // Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f(-size,  size, -size);    // Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f( size,  size, -size);    // Top Left Of The Texture and Quad
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f( size, -size, -size);    // Bottom Left Of The Texture and Quad
    
    // Top Face
    glBindTexture(GL_TEXTURE_2D,texture[2].texID);
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f(-size,  size, -size);    // Top Left Of The Texture and Quad
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f(-size,  size,  size);    // Bottom Left Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f( size,  size,  size);    // Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f( size,  size, -size);    // Top Right Of The Texture and Quad
    
    // Bottom Face       
    glBindTexture(GL_TEXTURE_2D,texture[3].texID);
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f(-size, -size, -size);    // Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f( size, -size, -size);    // Top Left Of The Texture and Quad
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f( size, -size,  size);    // Bottom Left Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f(-size, -size,  size);    // Bottom Right Of The Texture and Quad
    
    // Right face
    glBindTexture(GL_TEXTURE_2D,texture[4].texID);
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f( size, -size, -size);    // Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f( size,  size, -size);    // Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f( size,  size,  size);    // Top Left Of The Texture and Quad
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f( size, -size,  size);    // Bottom Left Of The Texture and Quad
    
    // Left Face
    glBindTexture(GL_TEXTURE_2D,texture[5].texID);
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f(-size, -size, -size);    // Bottom Left Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f(-size, -size,  size);    // Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f(-size,  size,  size);    // Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f(-size,  size, -size);    // Top Left Of The Texture and Quad
    
    glEnd();                                    // done with the polygon.
}
